package tpoo.common.dto.model.users;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import tpoo.common.dto.model.AbstractDTO;
import tpoo.common.dto.model.NotifactionCodes;
import tpoo.common.dto.model.ObjectID;
import tpoo.common.dto.model.ReceivedMessage;
import tpoo.common.dto.model.users.status.Presence;
import tpoo.common.services.UserService;
import tpoo.common.services.exceptions.ServiceException;
import tpoo.common.services.utils.ServiceAdmin;
import tpoo.common.services.utils.ServiceConstants;
import tpoo.common.utils.UserSession;

public class UserDTO extends AbstractDTO {

	private static final long serialVersionUID = 1L;

	private String username;

	public UserDTO(String username, Presence precence) {
		this.username = username;
		this.state = precence.toString();
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getUsername() {
		return username;
	}

	@Override
	public String toString() {
		return this.getUsername() + "(" + this.getState() + ")";
	}

	private Map<ObjectID, List<String>> messageBoard = new HashMap<ObjectID, List<String>>();

	public void receive(String message, ObjectID userID) {
		List<String> messages = messageBoard.get(userID);
		if (messages == null) // recien arrancan a hablar
			messageBoard.put(userID, new ArrayList<String>());
		this.setChanged();
		this.notifyObservers(new ReceivedMessage(userID, message));
		this.setLastMessage(userID + " sent " + message);
	}

	/*
	 * Hecho sólo para pruebas
	 */
	@Deprecated
	private String lastMessage = "";

	public void setLastMessage(String lastMessage) {
		this.getPropertyChangeSupport().firePropertyChange("lastMessage",
				this.lastMessage, this.lastMessage = lastMessage);
	}

	public String getLastMessage() {
		return lastMessage;
	}

	public void fireSessionStarted() {
		this.setChanged();
		this.notifyObservers(NotifactionCodes.SESSION_STARTED);
	}

	public void setState(String state) {
		this.getPropertyChangeSupport().firePropertyChange("state", this.state,
				this.state = state);
	}

	public String getState() {
		return state;
	}

	private String state = Presence.DO_NOT_DISTURB.toString();

	private List<UserDTO> contacts = new ArrayList<UserDTO>();

	// TODO ahora está refreshcontacts, analizar
	public void addContact(UserDTO contact) {
		getContacts().add(contact);
		// this.getPropertyChangeSupport().firePropertyChange("contacts", new
		// ArrayList(), getContacts());
		this.setChanged();
		this.notifyObservers(UPDATE_CONTACTS);
	}

	public void removeContact(UserDTO contact) {
		getContacts().remove(contact);
	}

	public void setContacts(List<UserDTO> contacts) {
		this.contacts = contacts;
	}

	public List<UserDTO> getContacts() {
		return contacts;
	}

	public UserDTO getContact(String username) {
		for (UserDTO cdto : this.getContacts()) {
			if (cdto.getUsername().equals(username))
				return cdto;
		}
		// TODO hacer una excepción más representativa
		throw new RuntimeException("No such contact (" + username + ")");
	}

	public void refreshContacts() {
		UserService us;
		try {
			us = (UserService) ServiceAdmin
					.getService(ServiceConstants.USER_SERVICE);
			List<UserDTO> contacts = us.getContacts(UserSession.getInstance()
					.getUser());
			this.contacts = contacts;
			this.setChanged();
			this.notifyObservers(UPDATE_CONTACTS);
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
